查看原文
其他

领域模型设计【实战篇】

姜冬金 技术琐话 2019-12-17

编者按:

一次领域建模的实战之旅(http://mp.weixin.qq.com/s?__biz=MzIxMzEzMjM5NQ==&mid=401359220&idx=1&sn=d27ca0179c3109b403915df9534c9719#rd)是12月底的一次实践活动,姜同学也参与了,他帅气好学有心,投稿了这篇文字。

前言

近期团队内组织了一次工作坊式的实践活动,来探索领域建模,在设计建模过程中也带来很多有思考和感

题目内容

A公司的收费方案:所有的电话被分为白天电话和晚上电话。白天电话的时间从早晨7; 00到晚上7:00,剩下的时间算为晚上。白天的电话费用:第1分钟98美分,接下来每分钟30美分。晚上的计费方式为:第1分钟70美分,接下来20分钟收20美分,其余的每分钟12美分。政府对每人每个月的第1个50美元的电话收6%的税,其余收4%的税。

要求: 1、完成该需求的领域模型

     2、考虑一定的扩展性

     3、使用你喜欢的语言对模型进行代码实现,并证明其符合需求预期。

建模过程

一、领域模型分析

在开始分析和建模之前,我们需要知道本次收费方案的目的是什么?经过小组讨论我们得出本次收费方案涉及以下几个核心述求:

1、  计费:针对不同时段通话进行

2、  计税:基于每个人每月的消费情况进计税


在明确本次建模的重心是计费和计税两个模块后,我们开始运用四色建模法进行领域分析。相关四色建模法资料可以参见以下链接:http://www.infoq.com/cn/articles/xh-four-color-modeling

在得到本次建模的核心模块后,我们继续整理本方案涉及的时标性对象(moment-interval),我们就得到了整个领域模型的骨干:


每次通话都会留下对应通话记录,计费系统通过每次通话明细产生对应的计费明细。考虑到按用户每月消费进行计税计算,计费明细汇总成对应的计费月汇总账单,便于计税使用。通过计税明细得到最终的计税总单。

在得到骨干之后,为了这个模型可以更好的描述业务概念,这时候我们需要补充一些实体对象。通常实体对象有三类:人,地点,物(party/place/thing)。

在这个基础上,我们可以进一步抽象这些实体事如果参与到各种不同的流程中去的,这时候,我们就需要增加用到角色(role):


最后再把一些需要描述的信息放入描述对象(description)。


 

二、领域模型设计

在分析出本次方案的领域模型后,我们继续进行下一步工作领域模型设计。

在上一阶段的分析过程中,我们已经明确了本次的核心服务是计费和计税。我们先基于计费进行相关的设计工作。

从本次需求我们可以看出,收费逻辑是基于通话及其时间范围的。然而收费后续针对通话的收费不局限于基于通话时间范围收费,同时也不局限于通话。我们把现有移动、电信的业务来看,我们可以随意抽象如下收费方式:

1、              96元A套餐,套餐内包含450分钟国内通话,80M流量,100条短信。其中超出套餐范围:通话0.15元每分钟,流量0.3元1M,短信0.1元每条。

2、              办理亲情号1元包每个月1000分钟通话。

3、              流量套餐10元200M,20元500M等等。

。。。

 

公司计费算法可能不断调整和变化,我们思考怎么去应对这种变化。基于已有经验,我们考虑引入规则中心概念,通过规则包装各个计算的差异性,解耦收费场景和计费逻辑的关系。规则中心通过配置化的能力建收费场景和对应计费规则的映射,相关计费算法抽象成一个个计费规则,同时每个计费规则抽象自身计费参数的配置化。

回过头来,我们再来分析计税逻辑,可以发现计税和计费都是进行一些计算处理得出最终信息,我们把计税也统一纳入计费模型,最后得出了以下模型:



通过领域服务设计,再回过头去分析领域服务和对应领域对象的关系,我们可以分析出以下几点:

1、  通话相关的模型属于应用模型,不属于系统的领域对象,计费对应不局限于通话。

2、  计税明细属于中间过程数据,属于领域对象。

3、  规则引擎相关的规则模型也应该属于核心领域模型。

通过上述领域对象分析,我们得出关键领域服务与对应领域对象的关系如下图:


最终我们抽象出系统内部组件图如下:


三、编码实现

本次活动的重心是领域建模,编码相关细节这里就不一一叙述。

 

总结

一、建模结果点评

各组完成建模后,通过模型的可用性、扩展性、清晰性三个方面对各组进行了相关的点评,点评结果如下:


可用性

扩展性

清晰性

第一组

领域模型缺少计费账单信息,没有办法解决跨月话费计税问题。

引入规则中心概念,为后续扩展提供了良好的支撑。

缺少域的划分,各个领域模型的职责边界不能很好的描述清楚。

第二组

领域模型设计可以满足本次需求,能够处理计费和计税问题。

引入规则中心概念,为后续扩展提供了良好的支撑。

缺少域的划分,各个领域模型的职责边界不能很好的描述清楚。

第三组

领域模型设计可以满足本次需求,能够处理计费和计税问题。

基于本次需求可以满足,针对后续业务的扩展设计有所不足。

针对本次涉及的模型划分出了账务域、业务域、计费域、计税域,很清晰的表达了各个域的职责和边界。

 

各组建模成果如下:

第一组



第二组

 

第三组

二、活动总结

经过本次实战活动,我们可以总结出以下几点内容是后续需要关注和提升的点:

协作方面

1、在临时组建的团队中,需要有人会成为团队的头狼,带领团队完成目标。头狼的领导力和协作力对最终目标的完成至关重要。

建模层面

1、当我们去进行建模的时候,不要马上跳跃到领域模型及其中属性,需要先通过有效的方式去进行业务分析和分解,通过分析结果得出最终的领域模型。

2、统一建模语言,在领域建模过程中要明确各个对象的术语,便于大家沟通且不产生歧义。

3、拥抱变化,在建模的时候,我们需要去抽象它未来的变化形态。例如本次建模核心之一是计费规则,从业务领域到实现域转换的时候,规则处理模块要考虑规则叠加优惠组合等情况,当下设计的实现成本。

三、参后感悟

这里就不一一列举谁谁感悟什么,总结下本次实战后的感悟。

收获的感悟:

1、  挺有意思的活动,从业务的角度来分析需求,提取实体,构建领域模型,再从业务模型映射到软件设计,跳出工程师的身份定位,从系统分析员的视角用建模描述需求,从架构师的维度来用设计匹配建模和活动,最终回归本质,用工程师的技能完成软件,是一次拓展思维,锻炼业务分析能力的实战

2、  对于领域建模,大家都在各自理解上提出了很多种建模方式,也学习到了很多不同的思考方式产出的模型,在这个过程中不同的问题解决方式有很强的碰撞,收获蛮多,这个很赞。

3、  通过一次实践小课题发现我们运用已有的架构和设计方法的频率已经降低了很多,需要不时回头重新用技术架构的眼光审视我们现有系统的合理性,让系统在不断做加法的同时也保持合理的结构。

针对领域建模知识的感悟:

4、  领域模型设计,不是直接的系统设计.需要清楚了解概念之间的差异。

5、  领域模型不是表的关系图,是对业务的高度抽象,将业务中的实体抽象出来,帮助我们理解和分析业务。

6、  模型设计要考虑清楚边界划分,模型归属的域范围,不要将不同范围的属性耦合到一个模型里。

7、  一个好的领域模式设计是可以指导后续详细分析展开以及编码的。

8、  领域模型本身同样需要考虑高内聚,低耦合,将同样的属性归集到一个模型中,模型间的耦合度不能太高。

针对建模过程的感悟:

1、  不要一上来需求都没有搞清楚就开始设计,即使设计得再漂亮,最终得到的结果也会是错的。

2、  系统分析和设计不要一开始就陷入细节,否则会抓不到整体,很容易走偏。

3、  人越多,越难达成一致,当意见迟迟达不成一致时,团队中需要一个拍板的人,确定一个方向,拿到结果。

4、  花了很多的时间来讨论模型和设计,貌似有了结论,实际到开工的时候,才发现最复杂的模块:电话计费没有考虑清楚怎么做。在实现的时候开发过程中还是用写一个复杂方法的方式来实现。

5、  从头到尾,都是自己的目标是怎么设计计费系统、怎么完成功能、怎么完成测试,因此在做这个过程中,就忘记的最终的初衷(通过高抽象的计费模型->来构建完整领域系统),这个也是平时工程师忽略掉的重要步骤。

针对后续改进的感悟:

1、  对自己来说,以前通常来说是直接出方案,而比较忽略前期一步一步分析的过程,这种方式往往会导致部分场景分析的缺失,所以自己在方法上需要有所改变。

2、  领域建模,有必要专门整一个培训,发现很多人对领域的理解、领域建模的方法和思路没有什么概念。

3、  一个临时组建的团队在做一个需求分析、设计的过程中需要有体系化的解决问题思路和执行步骤和分工。从当天的表现来看做得还不够体系,在接下来的工作中需要不断总结、学习和练习领域分析的方法、模式。

 

 

----------

本次建模采用四色建模法,四色建模法(Color UML)是由Peter Coad 发明的一种建模方法,将抽象出来的对象分成四种原型(archetype):

1、moment-interval,这种对象表示那些在某个时间点存在,或者会存在一段时间的,这样的对象往往表示了一次外界的请求,比如一次询价(Quotation),一次购买(Sale),这样的对象表示的都是系统的价值所在,所以也是最重要的一类对象,一般用粉红色来表示。这样的对象一般都有一个起始时间和终止时间,以及一个唯一的标识号,用来唯一的标识这一次客户请求,比如PolicyNo.

    2、Role, 这种对象表示的是一种角色,往往由人或者物来承担,会有相应的责任和权利,一般一个moment-interval对象会关联多个Role,比如说一次询价(Quotation)涉及到两个Role, 询价人(Quoter)和询价的产品(Product for Quotation), 这类对象是除moment-interval对象外最重要的一类对象,一般用黄色来表示。这类对象一般都有一些被moment-interval对象请求的操作,用来完成它们的职责。

   3、 Party,Place, orThing, 这种对象往往表示的是一种客观存在的事物,例如:人,组织,产品,配件等等,这些事物往往会在一种moment-interval 中扮演某个Role, 比如某个人会在一次购买中扮演Customer的角色,也可以在询价中扮演询价人的角色。这类对象第三重要,所以一般用绿色来表示。这类对象一般都有Name,Address等属性。

  4、Description,这种对象一般是分类用或者描述性的对象,一般某个Thing,Place,Party会属于某个Description,主要用来表示一类事物,它的属性一般都是这一类事物都有的属性,这类对象一般用蓝色来表示。这类对象一般都有type,defaultValue等属性。


    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存